home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / oop55.zip / WALLS.PAS < prev   
Pascal/Delphi Source File  |  1989-05-02  |  5KB  |  205 lines

  1.  
  2. { Copyright (c) 1989 by Borland International, Inc. }
  3.  
  4. unit Walls;
  5. { Turbo Pascal 5.5 object-oriented example.
  6.   See BREAKOUT.PAS.
  7.   This unit defines the Wall object type.
  8.   It's a fairly complex object, because it plays such a
  9.   pivotal role in the game.
  10. }
  11.  
  12. interface
  13.  
  14. uses Screen, Bricks, Bounds, Crt;
  15.  
  16. type
  17.   BrickPtr = ^Brick;
  18.   BW = array[1..1000] of Brick;
  19.   WallPtr = ^BW;
  20.  
  21.   Wall = object(Obstacle)
  22.     BrickWall : WallPtr;
  23.     Height : Integer;
  24.     NumLeft : Integer;
  25.     Value : Integer;
  26.     NCells : Integer;
  27.     constructor Init(InitX, InitY, InitWidth, InitHeight : Integer);
  28.     destructor Done; virtual;
  29.     procedure Show; virtual;
  30.     procedure Hide; virtual;
  31.     function Collide(var B : Ball) : Boolean; virtual;
  32.     function GetValue : Integer; virtual;
  33.     procedure Reset;
  34.   end;
  35.  
  36. implementation
  37.  
  38. function RandomColor(MaxColors : Integer) : Integer;
  39. var
  40.   C : Integer;
  41. begin
  42.   C := Random(MaxColors);
  43.   while C = (TextAttr SHR 4) do
  44.     C := Random(MaxColors);
  45.   RandomColor := C;
  46. end;
  47.  
  48. procedure Beep;
  49. begin
  50.   Sound(100);
  51.   Delay(20);
  52.   NoSound;
  53. end;
  54.  
  55. { A wall is an array of bricks.  Its constructor actually builds a
  56.   conformant array, so we don't have to hardcode the size of the
  57.   wall. }
  58.  
  59. constructor Wall.Init(InitX, InitY, InitWidth, InitHeight : Integer);
  60. begin
  61.   Obstacle.Init(InitX, InitY, InitWidth, False);
  62.   Height := InitHeight;
  63.   NCells := Width*5;
  64.   GetMem(BrickWall, Width*Height*SizeOf(Brick));
  65.   Reset;
  66. end;
  67.  
  68. destructor Wall.Done;
  69. begin
  70.   FreeMem(BrickWall, Width*Height*SizeOf(Block));
  71. end;
  72.  
  73. { This procedure could be made simpler, but you wouldn't get the slick
  74.   effect you see when the wall is built. }
  75.  
  76. procedure Wall.Show;
  77. var
  78.   CurCol : Integer;
  79.   Count : Integer;
  80.   CurBlock : Integer;
  81. begin
  82.   Visible := True;
  83.   NumLeft := Width*Height;
  84.   for CurCol := 1 to Width + Height - 1 do
  85.     for Count := 0 to Height - 1 do
  86.     begin
  87.       CurBlock := CurCol + Count*(Width-1);
  88.       if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
  89.       begin
  90.         BrickWall^[CurBlock].Show;
  91.         Delay(5);
  92.       end;
  93.     end;
  94.   GoToXY(X + (5*Width DIV 2) - 7, Y);
  95.   TextColor(WHITE);
  96.   Write('Turbo Breakout');
  97. end;
  98.  
  99. procedure Wall.Hide;
  100. var
  101.   CurCol : Integer;
  102.   Count : Integer;
  103.   CurBlock : Integer;
  104. begin
  105.   Visible := False;
  106.   for CurCol := 1 to Width + Height - 1 do
  107.     for Count := 0 to Height - 1 do
  108.     begin
  109.       CurBlock := CurCol + Count*(Width-1);
  110.       if (CurCol - Count >= 1) and (CurCol - Count <= Width) then
  111.       begin
  112.         if BrickWall^[CurBlock].IsVisible then
  113.         begin
  114.           BrickWall^[CurBlock].Hide;
  115.           Delay(5);
  116.         end;
  117.       end;
  118.     end;
  119. end;
  120.  
  121. function Wall.Collide(var B : Ball) : Boolean;
  122. var
  123.   CollideV, CollideH : Boolean;
  124.  
  125. { To check for a collision with a brick, first we check if the ball is in
  126.   the area where the wall is located, then we see if there's a brick that's
  127.   still visible at the ball's position.  If so, we destroy the brick, grab
  128.   its value, and beep. }
  129.  
  130. function CheckCollide(XPos, YPos : Integer) : Boolean;
  131. var
  132.   ThisBrick : BrickPtr;
  133. begin
  134.   CheckCollide := False;
  135.   if (YPos < Y) or (YPos > Y + Height - 1) or
  136.      (XPos < X) or (XPos > X + NCells - 1) then
  137.     Exit;
  138.   ThisBrick := @BrickWall^[1 + ((XPos-1) DIV 5) + Width*(YPos - 1)];
  139.   if ThisBrick^.IsVisible then
  140.   begin
  141.     CheckCollide := True;
  142.     Inc(Value, ThisBrick^.GetValue);
  143.     ThisBrick^.Hide;
  144.     Dec(NumLeft);
  145.     Beep;
  146.     if NumLeft = 0 then
  147.       Show;
  148.   end
  149. end;
  150.  
  151. { When checking for a collision with the wall, we have to watch out
  152.   for special cases involving corners. }
  153.  
  154. begin
  155.   Collide := False;
  156.   Value := 0;
  157.   CollideV := CheckCollide(B.X, B.NextY);
  158.   CollideH := CheckCollide(B.NextX, B.Y);
  159.   if CollideV then
  160.   begin
  161.     Collide := True;
  162.     B.ReverseY;
  163.   end;
  164.   if CollideH then
  165.   begin
  166.     Collide := True;
  167.     B.ReverseX;
  168.   end;
  169.   if not CollideV and not CollideH then
  170.     if CheckCollide(B.NextX, B.NextY) then
  171.     begin
  172.       Collide := True;
  173.       B.ReverseX;
  174.       B.ReverseY;
  175.     end;
  176. end;
  177.  
  178. function Wall.GetValue : Integer;
  179. begin
  180.     GetValue := Value;
  181. end;
  182.  
  183. procedure Wall.Reset;
  184. var
  185.   CurRow : Integer;
  186.   CurCol : Integer;
  187.   MaxColors : Integer;
  188. begin
  189.   if LastMode = Mono then
  190.     MaxColors := 4
  191.   else
  192.     MaxColors := 16;
  193.   NumLeft := Width*Height;
  194.   for CurRow := 0 to Height - 1 do
  195.     for CurCol := 0 to Width - 1 do
  196.       BrickWall^[CurRow*Width+CurCol+1].Init(X + CurCol*5,
  197.                                              Y + CurRow,
  198.                                              RandomColor(MaxColors),
  199.                                              Height - Y - CurRow + 1);
  200.   if Visible then
  201.     Show;
  202. end;
  203.  
  204. end.
  205.